package cn.thoughtworks.school.services;

import cn.thoughtworks.school.entities.Tag;
import cn.thoughtworks.school.entities.User;
import cn.thoughtworks.school.handlers.BusinessException;
import cn.thoughtworks.school.repositories.TagRepository;
import cn.thoughtworks.school.requestParams.YmlConvertQuiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TagService {
  @Autowired
  private TagRepository tagRepository;
  @Autowired
  private UserCenterService userCenterService;
  @Autowired
  private Utils utils;

  public Tag createTag(Map data, User current) throws BusinessException {
    Long organizationId = userCenterService.getUserCurrentOrganizationId(current.getId());
    Tag tag= tagRepository.findFirstByNameAndOrganizationId((String) data.get("name"), organizationId).get();
    if (Objects.nonNull(tag)) {
      throw new BusinessException("Current tag is already exist.");
    }
    tag = new Tag();
    tag.setMakerId(current.getId());
    tag.setReferenceNumber(0L);
    tag.setOrganizationId(organizationId);
    tag.setName((String) data.get("name"));
    tag.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    return tagRepository.save(tag);
  }

  public Page<Tag> findTagPageableByOrganization(Pageable pageable, User current) {
    Long organizationId = userCenterService.getUserCurrentOrganizationId(current.getId());
    Page<Tag> tagPage = tagRepository.findAllByOrganizationId(organizationId, pageable);
    return utils.format(tagPage, pageable);
  }

  public List<Tag> getTagsByOrganizationAndNameContaining(User user, String name, Pageable topTen) {
    Long organizationId = userCenterService.getUserCurrentOrganizationId(user.getId());
    return tagRepository.getTagsByOrganizationIdAndNameContaining(organizationId, name, topTen);
  }

  public List<Tag> findAllByOrganization(User user) {
    Long organizationId = userCenterService.getUserCurrentOrganizationId(user.getId());
    return tagRepository.findAllByOrganizationId(organizationId);
  }

  public List<Tag> findAllByOrganizationAndName(List<String> tagsName, Long organizationId) {
    return tagRepository.findAllByOrganizationIdAndNameIn(organizationId, tagsName);
  }

  public void saveAll(List<Tag> tags) {
    tagRepository.saveAll(tags);
  }
    protected List<Tag> updateTags(YmlConvertQuiz converter, Long organizationId, Long userId) {
        List<String> tagsName = new ArrayList<>(converter.getTags());
        List<Tag> foundTags = findAllByOrganizationAndName(tagsName, organizationId);
        List<Tag> needSaveTags = tagsName.stream()
            .filter(name -> {
                Optional<Tag> optional = foundTags.stream().filter(tag -> tag.getName().equals(name)).findFirst();
                return !optional.isPresent();
            })
            .map(name -> new Tag(name, userId, organizationId))
            .collect(Collectors.toList());
        saveAll(needSaveTags);
        needSaveTags.addAll(foundTags);
        return needSaveTags;
    }

}
